﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Elsa.Common;
using Elsa.Extensions;
using Elsa.Workflows;
using Elsa.Workflows.Activities.Flowchart.Models;
using Elsa.Workflows.IncidentStrategies;
using Elsa.Workflows.Models;
using Elsa.Workflows.State;
using Newtonsoft.Json;
using T.FAS.Runtime.MF.Dao;
using T.FAS.Runtime.MF.SPI;

namespace T.FAS.Runtime.MF.Activities.Extensions
{
    public static class ActivityExecutionContextExtensions
    {
        public static async ValueTask FaultAndComplete(this ActivityExecutionContext context, Exception e, IActivityWithExceptionHandle activity)
        {
            var currentActivity = context.Activity;
            if (activity.FaultedStrategy == "返回默认值")
            {
                //用默认值填充变量
                foreach (var item in activity.ActivityOutputVariables)
                {
                    var varName = item.Name.Replace($"{currentActivity.Id}:", "");
                    if (activity.DefaultValuesWhenException.ContainsKey(varName))
                    {
                        var varValue = activity.DefaultValuesWhenException[varName];
                        context.SetVariable(item.Name, varValue);
                    }
                }

                foreach (var item in activity.DoneOutcomes)
                {
                    await context.CompleteActivityWithOutcomesAsync(new[] { item });
                }
               

                var incidentStrategyResolver = context.GetRequiredService<IIncidentStrategyResolver>();
                var strategy = await incidentStrategyResolver.ResolveStrategyAsync(context);
                strategy.HandleIncident(context);

               
            }
            else if (activity.FaultedStrategy == "节点停止运行")
            {
                context.Exception = e;
                context.TransitionTo(ActivityStatus.Faulted);

                
                var exceptionState = ExceptionState.FromException(e);
                var systemClock = context.GetRequiredService<ISystemClock>();
                var now = systemClock.UtcNow;
                var incident = new ActivityIncident(currentActivity.Id, currentActivity.NodeId, currentActivity.Type, e.Message, exceptionState, now);
                context.WorkflowExecutionContext.Incidents.Add(incident);
                context.TransitionTo(ActivityStatus.Faulted);

                //var incidentStrategyResolver = context.GetRequiredService<IIncidentStrategyResolver>();
                //var strategy = await incidentStrategyResolver.ResolveStrategyAsync(context);
                //strategy.HandleIncident(context);
            }
            else if (activity.FaultedStrategy == "异常分支")
            {
                foreach (var outcome in activity.ExceptionOutcomes??new List<string>())
                {
                    await context.CompleteActivityWithOutcomesAsync(outcome);
                }
            }
            else if (activity.FaultedStrategy == "终止整个工作流")
            {
                context.Exception = e;
                context.TransitionTo(ActivityStatus.Faulted);

                var exceptionState = ExceptionState.FromException(e);
                var systemClock = context.GetRequiredService<ISystemClock>();
                var now = systemClock.UtcNow;
                var incident = new ActivityIncident(currentActivity.Id, currentActivity.NodeId, currentActivity.Type, e.Message, exceptionState, now);
                context.WorkflowExecutionContext.Incidents.Add(incident);
                context.TransitionTo(ActivityStatus.Faulted);

                var incidentStrategyResolver = context.GetRequiredService<IIncidentStrategyResolver>();
                var strategy = await incidentStrategyResolver.ResolveStrategyAsync(context);
                strategy.HandleIncident(context);
            }

        }

        public static  void SetIterationVariableValue(this ActivityExecutionContext context, string variableName, object variableValue)
        {
            var iterationResultVarName = $"{variableName}{MFConst.IterationResultVariableSuffix}";

            //LogUtil.Log($"当前iterationResultVarName={iterationResultVarName}：variableValue={JsonConvert.SerializeObject(variableValue)}");
            //var varValue = context.GetVariable<object[]>(iterationResultVarName);
            //LogUtil.Log($" context.GetVariable<object>(iterationResultVarName)={JsonConvert.SerializeObject(varValue)}");
            //if (varValue == null)
            //{
            //    LogUtil.Log($" 第一次放入数据={JsonConvert.SerializeObject(new List<object> { variableValue })}");
            //    context.SetVariable(iterationResultVarName, new object[] { variableValue });
            //}
            //else
            //{
            //    LogUtil.Log($" 第二次获取数据{iterationResultVarName},Type={varValue.GetType()},Value={JsonConvert.SerializeObject(varValue)}");
            //    var currnetValues = varValue.ToList();
            //    LogUtil.Log($" context.GetVariable<object>(iterationResultVarName).currnetValues={JsonConvert.SerializeObject(currnetValues)}");
            //    currnetValues.Add(variableValue);
            //    context.SetVariable(iterationResultVarName, currnetValues.ToArray());
            //}
            var v = context.GetVariableValues();

            LogUtil.Log($"当前iterationResultVarName={iterationResultVarName}：variableValue={JsonConvert.SerializeObject(variableValue)}");
            var varValue = context.GetVariable<object[]>(iterationResultVarName);
            LogUtil.Log($" context.GetVariable<object>(iterationResultVarName)={JsonConvert.SerializeObject(varValue)}");
            if (varValue == null)
            {
                LogUtil.Log($" 第一次放入数据={JsonConvert.SerializeObject(new List<object> { variableValue })}");
                context.SetVariable(iterationResultVarName, new List<object> { variableValue });
            }
            else
            {
                LogUtil.Log($" 第二次获取数据{iterationResultVarName},Type={varValue.GetType()},Value={JsonConvert.SerializeObject(varValue)}");
                if(varValue.GetType() == typeof(List<object>))
                {
                    var currnetValues = new List<object> { varValue };
                    currnetValues.Add(variableValue);
                    context.SetVariable(iterationResultVarName, currnetValues);
                }
                else
                {
                    var currnetValues = varValue.ToList();
                    LogUtil.Log($" context.GetVariable<object>(iterationResultVarName).currnetValues={JsonConvert.SerializeObject(currnetValues)}");
                    currnetValues.Add(variableValue);
                    context.SetVariable(iterationResultVarName, currnetValues);
                }
            }
        }
    }
}
